#include "i2c.h"

extern i2c_handle_type hi2cx;

/**
  * @brief  initializes peripherals used by the i2c.
  * @param  none
  * @retval none
  */
void i2c_lowlevel_init(i2c_handle_type* hi2c)
{
  gpio_init_type gpio_init_structure;

  if(hi2c->i2cx == I2Cx_PORT)
  {
    /* i2c periph clock enable */
    crm_periph_clock_enable(I2Cx_CLK, TRUE);
    crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
    crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);

    /* gpio configuration */
    gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);

    gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);

    /* configure i2c pins: scl */
    gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_structure.gpio_mode           = GPIO_MODE_MUX;
    gpio_init_structure.gpio_out_type       = GPIO_OUTPUT_OPEN_DRAIN;
    gpio_init_structure.gpio_pull           = GPIO_PULL_UP;

    gpio_init_structure.gpio_pins           = I2Cx_SCL_GPIO_PIN;
    gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);

    /* configure i2c pins: sda */
    gpio_init_structure.gpio_pins           = I2Cx_SDA_GPIO_PIN;
    gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);

    /* config i2c */
    i2c_init(hi2c->i2cx, 0x00, I2Cx_CLKCTRL);

    i2c_own_address1_set(hi2c->i2cx, I2C_ADDRESS_MODE_7BIT, I2Cx_ADDRESS);
  }
}

void II2C_Gpio_Init(void)
{
#if 0
		gpio_init_type gpio_init_struct;
		/* enable gpioc periph clock */
		crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);


		gpio_default_para_init(&gpio_init_struct);	

		/* gpio output config */
		gpio_bits_write(GPIOC, IO_SCL_PIN | IO_SDA_PIN, TRUE);

		gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
		gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
		gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
		gpio_init_struct.gpio_pins = IO_SCL_PIN | IO_SDA_PIN;
		gpio_init_struct.gpio_pull = GPIO_PULL_UP;
		gpio_init(GPIOC, &gpio_init_struct);
#else
		gpio_init_type gpio_init_structure;
		crm_periph_clock_enable(I2Cx_CLK, TRUE);
		crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
		crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);

		/* gpio configuration */
		gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);

		gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);

		/* configure i2c pins: scl */
		gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
		gpio_init_structure.gpio_mode           = GPIO_MODE_MUX;
		gpio_init_structure.gpio_out_type       = GPIO_OUTPUT_OPEN_DRAIN;
		gpio_init_structure.gpio_pull           = GPIO_PULL_UP;

		gpio_init_structure.gpio_pins           = I2Cx_SCL_GPIO_PIN;
		gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);

		/* configure i2c pins: sda */
		gpio_init_structure.gpio_pins           = I2Cx_SDA_GPIO_PIN;
		gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);

		hi2cx.i2cx = I2Cx_PORT;

		/* i2c config */
		i2c_config(&hi2cx);
#endif

}
/*****************************************************************************
 * @name       :void IIC_Start(void)
 * @date       :2018-09-13 
 * @function   :start iic bus
 * @parameters :None
 * @retvalue   :None
******************************************************************************/
void IIC_Start(void) {
	OLED_SCL_SET();
	OLED_SDA_SET();
	OLED_SDA_CLR();
	OLED_SCL_CLR();
}

/*****************************************************************************
 * @name       :void IIC_Stop(void)
 * @date       :2018-09-13 
 * @function   :stop iic bus
 * @parameters :None
 * @retvalue   :None
******************************************************************************/
void IIC_Stop(void) {
	OLED_SCL_SET();
	OLED_SDA_CLR();
	OLED_SDA_SET();
}

/*****************************************************************************
 * @name       :void IIC_Wait_Ack(void)
 * @date       :2018-09-13 
 * @function   :wait iic ack
 * @parameters :None
 * @retvalue   :None
******************************************************************************/
void IIC_Wait_Ack(void) {
	OLED_SCL_SET();
	OLED_SCL_CLR();
}

/*****************************************************************************
 * @name       :void Write_IIC_Byte(uint8_t IIC_Byte)
 * @date       :2018-09-13 
 * @function   :Write a byte of content with iic bus
 * @parameters :IIC_Byte
 * @retvalue   :None
******************************************************************************/
void Write_IIC_Byte(uint8_t IIC_Byte) {
	i2c_status_type i2c_status;
	#if 0
	uint8_t i;
	uint8_t m,da;
	da=IIC_Byte;
	OLED_SCL_CLR();
	for(i=0;i<8;i++) {
		m=da;
		m=m&0x80;
		if(m==0x80) {
			OLED_SDA_SET();
		} else {
			OLED_SDA_CLR();
		}
		da=da<<1;
		OLED_SCL_SET();
		OLED_SCL_CLR();
	}
	#else
	uint8_t buff[2] = {0};
	buff[0] = IIC_Byte;
	i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, buff, 1, 1000);
	if(i2c_status != I2C_OK)
	{
		;//printf("erro send %d",i2c_status);
	}
	#endif
}

/*****************************************************************************
 * @name       :void Write_IIC_Command(uint8_t IIC_Command)
 * @date       :2018-09-13 
 * @function   :Write a byte of command to oled screen
 * @parameters :IIC_Command:command to be written
 * @retvalue   :None
******************************************************************************/
void Write_IIC_Command(uint8_t IIC_Command) {
	i2c_status_type i2c_status;
	#if 0
	IIC_Start();
	Write_IIC_Byte(IIC_SLAVE_ADDR);            //Slave address,SA0=0
	IIC_Wait_Ack();	
	Write_IIC_Byte(0x00);			//write command
	IIC_Wait_Ack();	
	Write_IIC_Byte(IIC_Command); 
	IIC_Wait_Ack();	
	IIC_Stop();
	#else
	uint8_t buff[2] = {0};
	buff[0] = 0x00;
	buff[1] = IIC_Command;
	i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, buff, 2, 1000);
	if(i2c_status != I2C_OK)
	{
		;//printf("erro send %d",i2c_status);
	}
	#endif
}

/*****************************************************************************
 * @name       :void Write_IIC_Data(uint8_t IIC_Data)
 * @date       :2018-09-13 
 * @function   :Write a byte of data to oled screen
 * @parameters :IIC_Data:data to be written
 * @retvalue   :None
******************************************************************************/
void Write_IIC_Data(uint8_t IIC_Data) {
	i2c_status_type i2c_status;
	#if 0
	IIC_Start();
	Write_IIC_Byte(IIC_SLAVE_ADDR);			//D/C#=0; R/W#=0
	IIC_Wait_Ack();	
	Write_IIC_Byte(0x40);			//write data
	IIC_Wait_Ack();	
	Write_IIC_Byte(IIC_Data);
	IIC_Wait_Ack();	
	IIC_Stop();
	#else
	uint8_t buff[2] = {0};
	buff[0] = 0x40;
	buff[1] = IIC_Data;
	i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, buff, 2, 1000);
	if(i2c_status != I2C_OK)
	{
		;//printf("erro send %d",i2c_status);
	}
	#endif
}
